import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider

# 初始化参数和采样设置
N = 1000  # 采样点数
x = np.linspace(0, 4 * np.pi, N)  # x 范围 [0, 4π]

# 定义信号生成函数
def generate_signal(A, n, B, m):
    return A * np.sin(n * x) + B * np.sin(m * x)

# 计算傅里叶变换
def compute_fft(signal):
    fft_result = np.fft.fft(signal)  # 快速傅里叶变换
    magnitude = np.abs(fft_result[:N//2])  # 取前半部分（对称性）
    frequency = np.fft.fftfreq(N, d=(x[1]-x[0]))[:N//2]  # 频率轴
    return frequency, magnitude

# 动态绘图函数
def plot_signal(A=1.0, n=1.0, B=0.5, m=3.0):
    signal = generate_signal(A, n, B, m)
    freq, mag = compute_fft(signal)
    
    # 创建画布
    plt.figure(figsize=(12, 6))
    
    # 时域图
    plt.subplot(1, 2, 1)
    plt.plot(x, signal, 'b-', linewidth=2)
    plt.title('Time Domain: $f(x) = A \sin(n x) + B \sin(m x)$')
    plt.xlabel('x')
    plt.ylabel('Amplitude')
    plt.grid(True)
    
    # 频域图（频谱）
    plt.subplot(1, 2, 2)
    plt.plot(freq, mag, 'r-', linewidth=2)
    plt.title('Frequency Domain (FFT)')
    plt.xlabel('Frequency (Hz)')
    plt.ylabel('Magnitude')
    plt.grid(True)
    plt.tight_layout()
    plt.show()

# 创建交互控件
interact(
    plot_signal,
    A=FloatSlider(min=0.1, max=3.0, step=0.1, value=1.0, description='A:'),
    n=FloatSlider(min=0.5, max=5.0, step=0.5, value=1.0, description='n:'),
    B=FloatSlider(min=0.1, max=3.0, step=0.1, value=0.5, description='B:'),
    m=FloatSlider(min=0.5, max=10.0, step=0.5, value=3.0, description='m:')
);